#ifndef __PFIFO_H__
#define __PFIFO_H__

#include <stdint.h>
#include <errno.h>
#include <string.h>

#undef ENABLE_CROSS_DEVICE_BUILD
#define ENABLE_CROSS_DEVICE_BUILD   1
#define SHM_CACHELINE_BYTES     	64
#define SHM_MESG_SIZE				(SHM_CACHELINE_BYTES * 2)

#ifndef __packed
#define __packed            __attribute__((__packed__))
#endif

#ifndef static_assert
#define static_assert(e, ...)       extern void _static_assert(int arg[(e) ? 1 : -1])
#endif

#undef __xfifo
#undef XFIFO_FUNC
#define __xfifo             pfifo
#define XFIFO_FUNC(name)        pfifo_##name

#undef __xmesg
#undef XMESG
#undef __XMESG_SIZE
#define __xmesg             pmesg
#define XMESG(name)			pmesg_##name
#define	__XMESG_SIZE		64

#include "_fifo.h"

#if BUILD_PFIFO_INLINE
#define __static_inline         static inline
#include "_fifo.ch"
#else
#define __static_inline

struct __xfifo;

int pfifo_initialized(struct __xfifo *fifo);
int pfifo_init(struct __xfifo *fifo, void *data, uint32_t size, uint32_t esize);
uint32_t pfifo_size(struct __xfifo *fifo);
uint32_t pfifo_used_len(struct __xfifo *fifo);
uint32_t pfifo_unused_len(struct __xfifo *fifo);
int pfifo_is_empty(struct __xfifo *fifo);
int pfifo_is_full(struct __xfifo *fifo);
void *pfifo_data(struct __xfifo *fifo, uint32_t offset);
void *pfifo_data_mem(struct __xfifo *fifo);
int pfifo_enqueue_len(struct __xfifo *fifo, void *data, uint32_t len);
int pfifo_enqueue_overlay_len(struct __xfifo *fifo, void *data, uint32_t len);
int pfifo_dequeue_len(struct __xfifo *fifo, void *dest, uint32_t len);
int pfifo_peek_len(struct __xfifo *fifo, void *dest, uint32_t len);
int pfifo_skip_len(struct __xfifo *fifo, uint32_t len);
uint32_t pfifo_used_count(struct __xfifo *fifo);
uint32_t pfifo_unused_count(struct __xfifo *fifo);
int pfifo_enqueue(struct __xfifo *fifo, void *data);
int pfifo_enqueue_overlay(struct __xfifo *fifo, void *data);
int pfifo_dequeue(struct __xfifo *fifo, void *dest);
int pfifo_peek(struct __xfifo *fifo, void *dest);
int pfifo_skip(struct __xfifo *fifo);

#endif
#endif
